// import 'dart:async';
import 'dart:async';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_kit_audio/flutter_kit_audio.dart';
import 'package:flutter_kit_mic/flutter_kit_mic.dart';
import 'package:flutter_kit_plus/flutter_kit.dart';
import 'package:get/get.dart';
import 'package:roswell_rgbw/bluetooth/blemanager_extension.dart';
import 'package:roswell_rgbw/const/const.dart';

import '../../bluetooth/blue_data_model.dart';
import '../../bluetooth/send_data.dart';
import '../../routes/app_pages.dart';

class SliderModel {
  int min = 0;
  int max = 0;
  int value = 0;
  SliderModel({required this.min, required this.max, required this.value});
}

class HomeController extends GetxController with WidgetsBindingObserver {
  late final CircularColorPicker picker;
  RxList<bool> tabState = [false, false, false].obs;
  RxList<String> types = ['RING', 'WHT DM'].obs;
  RxString type = 'RING'.obs;
  RxList<int> colorItems = [0].obs;
  RxList<String> colorKeys = [''].obs;
  RxInt colorIndex = 7.obs;
  Rx<SliderModel> brt = SliderModel(min: 1, max: 10, value: 10).obs;
  Rx<SliderModel> spd = SliderModel(min: 1, max: 31, value: 5).obs;
  RxList<Map<String, int>> colorModeList = [
    {'': 0},
  ].obs;
  RxInt colorModeIndex = 100.obs;
  // StreamController<Uint8List> _audioStreamController = StreamController<Uint8List>();
  StreamController<Uint8List> _audioStreamController = StreamController<Uint8List>.broadcast();
  StreamSubscription<Uint8List>? _micSubscription;
  Stream<Uint8List>? _sub;
  RxList device_data_list = [].obs;
  RxList<int> currentColor = [0x00, 0x00, 0x00, 0x00].obs;
  List<String> get tabIcons {
    return [
      tabState[0] ? assets.mic_on : assets.mic_off,
      tabState[1] ? assets.turn_on : assets.turn_off,
      tabState[2] ? assets.set_select : assets.set,
    ];
  }

  @override
  void onInit() {
    super.onInit();
    WidgetsBinding.instance.addObserver(this);
    initData();

    processAudioStream();
    colorItems = List.filled(14, 0).obs;
    colorItems[0] = 0xFFFF0000;
    colorItems[1] = 0xFF00FF00;
    colorItems[2] = 0xFF0000FF;
    colorItems[3] = 0xFFFFFFFF;
    colorItems[4] = 0xFFFFFFFF;
    colorItems[5] = 0xFFFFFF00;
    colorItems[6] = 0xFF00FFFF;

    colorKeys = List.filled(14, '').obs;
    colorKeys[0] = 'R';
    colorKeys[1] = 'G';
    colorKeys[2] = 'B';
    colorKeys[3] = 'W';
    colorKeys[4] = 'RGBW';
    colorKeys[5] = 'yellow';
    colorKeys[6] = 'cyan';

    colorModeList = [
      {'Seven-Color Gradient': 0x25},
      {'Red Gradient': 0x26},
      {'Green Gradient': 0x27},
      {'Blue Gradient': 0x28},
      {'Yellow Gradient': 0x29},
      {'Cyan Gradient': 0x2A},
      {'Purple Gradient': 0x2B},
      {'White Gradient': 0x2C},
      {'Red-Green Gradient': 0x2D},
      {'Red-Blue Gradient': 0x2E},
      {'Green-Blue Gradient': 0x2F},
      {'Seven-Color Strobe': 0x30},
      {'Red Strobe': 0x31},
      {'Green Strobe': 0x32},
      {'Blue Strobe': 0x33},
      {'Yellow Strobe': 0x34},
      {'Cyan Strobe': 0x35},
      {'Purple Strobe': 0x36},
      {'White Strobe': 0x37},
      {'Seven Color Jump': 0x38},
    ].obs;
  }

  Future<void> initData() async {
    var brtstr = await getValue(key: 'key');
    brt.value.value = brtstr == '' ? 5 : brtstr.intValue;

    for (int i = (colorItems.length / 2).toInt(); i < colorItems.length; i++) {
      String color = await getValue(key: '$i');
      colorItems[i] = color.intValue;
    }
    currentColor.value = colorItems[colorIndex.value].bytes;
  }

  int code(int value) => (value * (brt.value.value) / 10.0).round();
  int decode(int value) => min(255, (value * 10.0 / (brt.value.value)).round());

  ///获取是rgb还是w的 标志位
  int isRGB() {
    return (colorKeys[colorIndex.value] == 'W' || type.value == types[1]) ? 0x0F : 0xF0;
  }

  ///获取暖白值
  int getWhite() {
    int white = 0x00;
    if (isRGB() == 0x0F) {
      white = (0xFF / brt.value.max * brt.value.value).toInt();
    } else {
      white = 0x0;
    }
    return white;
  }

  ///点击底部 按钮
  void tapBottom(BuildContext context, int index) async {
    switch (index) {
      case 0:
        tabState[index] = !tabState[index];
        bool status = await prepareOpenMic(context, tabState[index]);
        if (status == false) {
          tabState[index] = false;
        }
        break;
      case 1:
        tabState[index] = !tabState[index];
        tabState[0] = tabState[index] ? tabState[0] : false;
        sendTurnState();
        stopRecorder();
        break;
      case 2:
        Get.toNamed(Routes.SETTING);
        tabState[index] = true;
        Future.delayed(const Duration(milliseconds: 100), () => tabState[index] = false);
        break;
      default:
    }
  }

  // 更改ring | wht dm
  void changeType(int index) {
    type.value = types[index];
    picker.cirulaImage = index == 0 ? assets.color : assets.color2;
    colorIndex.value = 7;
    picker.kstate.reloadCirulaImage();
  }

  ///色盘上颜色更新
  void updateCircleColor(List<int> p0) {
    currentColor.value = [0xFF, ...p0];
    if (colorIndex > 6) {
      ///选择变动格子，更新格子里的颜色，并保存到本地
      colorItems[colorIndex.value] = [0xFF, ...p0].decimal;
      save(key: '${colorIndex.value}', value: '${currentColor.decimal}');
    }
    sendColor();
  }

  // 选中颜色item
  void selectColorItem(int index) {
    ///如果 是wht dm 模式，不能点击rgb颜色模块，只能点击w，和自定义的颜色格子
    if (type.value == types[1] && colorKeys[index] != 'W' && index < 7) {
      return;
    }
    colorIndex.value = index;
    int colorHex = colorItems[index];
    List<int> list = colorHex.bytes;
    if (list.length > 3) {
      currentColor.value = colorHex.bytes;
      sendColor();

      ///只有在ring模式，才刷新色盘的着色点。
      if (type.value == types[0]) {
        picker.kstate.setInitialColor(Color.fromARGB(list[0], list[1], list[2], list[3]));
      }

      ///保存自由 选择
      if (index > 6) {
        save(key: '$index', value: '#$colorHex');
      }
    }
  }

  ///清除颜色格子
  void deleteColorItem(int index) {
    if (index > 6) {
      colorItems[index] = 0;
    }
    delete('$index');
  }

  ///滚动颜色类型
  void updateColorMode(int index) {
    colorModeIndex.value = index;
    FlutterKitAudio.customSound(soundType: FlutterKitAudioCustomSoundType.click18);
    sendLEDType();
  }

  ///更新速度
  void updateSpeed(double speed, bool issend) {
    spd.value.value = speed.round();
    if (issend) {
      sendLEDType();
    }
  }

  ///更新亮度
  void updateBright(double bright, bool issend) {
    brt.value.value = bright.round();
    save(key: 'bright', value: '${brt.value.value}');
    if (issend) {
      sendColor();
    }
  }

  ///发送单色颜色
  void sendColor() {
    if (colorIndex.value >= colorItems.length) {
      return;
    }
    List<int> list = currentColor.length > 3 ? currentColor.sublist(1, 4) : currentColor.padLeft(3);

    print('===========>选中格子颜色 ${list.toHexstr('|')}.  ${isRGB()},  ${getWhite()}');
    for (DataModel model in device_data_list) {
      int red = list.isEmpty ? model.red : list[0];
      int green = list.isEmpty ? model.green : list[1];
      int blue = list.isEmpty ? model.blue : list[2];
      print('==============>   rgb = $red,$green,$blue');
      model.red = code(red);
      model.green = code(green);
      model.blue = code(blue);
      SendData.send('单色模式', [model.red, model.green, model.blue, getWhite(), isRGB()]);
    }
  }

  ///发送led固定显示模式
  void sendLEDType() {
    for (DataModel model in device_data_list) {
      if (colorModeIndex.value < colorModeList.length) {
        model.type = colorModeList[colorModeIndex.value].values.first;
      }
      model.speed = spd.value.value;
      SendData.send('指定颜色模式', model);
    }

    ///关闭mic状态
    tabState[0] = false;
    stopRecorder();
  }

  ///发送开关
  void sendTurnState() {
    for (var model in device_data_list) {
      model.isOn = tabState[1];
      SendData.send('开关', tabState[1]);
    }
  }

  void listenBT(BuildContext context) {
    listenBluetooth(context);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // 监听 App 生命周期变化
    if (state == AppLifecycleState.hidden) {
      // App 进入后台
      print('App 进入后台');
    } else if (state == AppLifecycleState.resumed) {
      // App 回到前台
      print('App 回到前台');
    }
  }
}

///保存数据
extension _MyHomeStateExtesion2 on HomeController {
  Future<void> save({required String key, required String value}) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(key, value);
  }

  Future<String> getValue({required String key}) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key) ?? '';
  }

  Future<void> delete(String key) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(key);
  }
}

extension _MyAppStateExtension on HomeController {
  void listenBluetooth(BuildContext context) {
    ///监听蓝牙外设连接状态
    BluetoothManager.instance.connectionStateStream.listen((value) {
      var state = value.values.first;
      switch (state) {
        case BluetoothConnectionState.connected:
          EasyLoading.showSuccess('Connect successfully');
          BluetoothManager.instance.isConnectedRx = true;
          listenData();
          SendData.send('查询数据', '');
        case BluetoothConnectionState.disconnected:
          BluetoothManager.instance.isConnectedRx = false;
          EasyLoading.showSuccess('Disconnected!', duration: const Duration(milliseconds: 1500));
          tabState.value = [false, false, false].obs;
          stopRecorder();
        case BluetoothConnectionState.connecting:
          break;
        case BluetoothConnectionState.disconnecting:
          print('设备断开连接中');
          break;
      }
    });

    ///监听蓝牙广播状态
    BluetoothManager.instance.bluetoothStateStream.listen(
      (state) {
        switch (state) {
          case BluetoothAdapterState.on:
            break;
          case BluetoothAdapterState.off:
            BluetoothManager.instance.isConnectedRx = false;
          //EasyLoading.showInfo('Bluetooth turned off');
          default:
        }
      },
      onError: (error) {
        EasyLoading.showInfo('${error.message}');
      },
    );
  }

  void listenData() {
    ///监听数据回调
    BluetoothManager.instance.read(
      service_uuid: read_service,
      characteristics_uuid: read_uuid,
      onResponse: (data) {
        print('收到蓝牙上传的数据是 == ${data.toHexstr(' |')}');
        if (data.length >= 12 && data[0] == 0x66) {
          tabState.value = [false, data[2] == 0x23, true];
          DataModel model = DataModel(
            name: data[1].bytes.toHexstr(),
            isOn: data[2] == 0x23,
            type: data[3],
            isPlay: data[4] == 0x20,
            speed: 32 - data[5],
            red: decode(data[6]),
            green: decode(data[7]),
            blue: decode(data[8]),
            warmWhite: data[9],
            version: data[10],
          );
          GlobalDataNotifier().updateData(model);
          if (device_data_list.any(($0) => $0.name == model.name) == false) {
            device_data_list.add(model);
          }
        }
      },
    );
  }
}

///录音操作
extension HomeControllerExtension3 on HomeController {
  ///预请求，运行时请求 权限
  Future<bool> prepareOpenMic(BuildContext context, bool isOpen) async {
    var result = await FlutterKitMic.requestPermission();
    print('请求结果1111: $result');
    if (!result) {
      // 引导用户去设置里开启
      return false;
    }
    if (result) {
      // 权限已被授予，可以开始录音
      if (isOpen) {
        openRecorder();
      } else {
        stopRecorder();

        for (DataModel model in device_data_list) {
          SendData.send('单色模式', [model.red, model.green, model.blue, getWhite(), isRGB()]);
        }
      }
      return true;
      // isOpen ? openRecorder() : stopRecorder();
    } else {
      showAlert(context, 'MIC requires recording permissions $result', ['OK'], (p1) {
        Permission.microphone.request();
      });
      return false;
    }
  }

  ///打开mic录音
  void openRecorder() async {
    await FlutterKitMic.startRecorder();
  }

  ///关闭mic录音
  void stopRecorder() async {
    await FlutterKitMic.stopRecorder();
  }

  ///接收到 录音收音数据流
  void processAudioStream() async {
    // 假设referencePressure是参考声压
    double referencePressure = 20.0 * pow(10, -6);
    bool receive = true;
    _sub = FlutterKitMic.pcmStream();
    _sub!.listen((bytes) {
      if (receive == false) {
        return;
      }
      receive = false;
      Future.delayed(const Duration(milliseconds: 200), () {
        receive = true;
      });

      double rms = calculateRMS(bytes as List<int>); // 计算音频数据的RMS值
      print('=============>.   rms. :$rms');

      if (rms < 1) return; // 系统后台填充0，忽略

      double db = 20 * log(rms / referencePressure); // 转换为分贝
      // 如果音频分贝低于噪声阈值，认为是背景噪音，不进行处理
      // if (db < noiseThreshold) {
      //   print("背景噪音，忽略");
      //   return;
      // }

      controlLED(db); // 根据分贝值控制LED
    });
  }

  void controlLED(double db) {
    // 根据分贝值控制LED灯的逻辑
    // 这里需要实现具体的LED控制逻辑

    // 1. 限制 dB 范围，避免 dB 值过高或过低
    db = db.clamp(320, 420); // 限制 dB 在合理范围内

    // // 2. 计算 RGB 每个通道的值
    // int red, green, blue;

    // // 使用对数映射来调整 RGB 值，避免高 dB 值过于剧烈
    // red = logMapping(db, 330.0, 420.0, 0, 255); // 红色通道：高 dB 值时红色最强
    // green = logMapping(db, 330.0, 420.0, 0, 255); // 绿色通道：中等 dB 值时绿色最强
    // blue = logMapping(db, 330.0, 420.0, 0, 255); // 蓝色通道：低 dB 值时蓝色最强

    // 打印 RGB 调整结果，供调试使用
    // print('===============> 录入音频数据  ==== red = ${red} ， green = ${green}, blue = ${blue}');
    double s = max(0, db - 320) / 45;
    for (DataModel model in device_data_list) {
      SendData.send('单色模式', [
        (model.red * s).toInt(),
        (model.green * s).toInt(),
        (model.blue * s).toInt(),
        getWhite(),
        isRGB(),
      ]);
    }

    // SendData.send('手机麦克风收音', [red, green, blue]);
    // 这里可以使用调整后的 RGB 值去控制 LED 或其他显示效果
    // controlLED(red, green, blue);  // 控制 LED
  }

  ///计算音频数据的RMS（Root Mean Square，均方根）
  double calculateRMS(List<int> data) {
    // 假设data是16位的PCM音频数据，每个样本占用2个字节
    int numSamples = data.length ~/ 2;
    double sumSquares = 0.0;

    for (int i = 0; i < data.length; i += 2) {
      // 将两个字节组合成一个16位的样本值（小端序）
      int sample = (data[i] & 0xFF) | ((data[i + 1] & 0xFF) << 8);
      // 将16位有符号整数转换为有符号的32位整数
      if (sample > 32767) {
        sample -= 65536;
      }
      // 计算平方并累加
      sumSquares += sample * sample;
    }

    // 计算平均值
    double meanSquare = sumSquares / numSamples;
    // 取平方根得到RMS值
    double rms = sqrt(meanSquare);
    return rms;
  }

  /// 使用对数映射 dB 到 RGB 范围
  int logMapping(double db, double minDb, double maxDb, int minColor, int maxColor) {
    // 如果 db 小于 minDb，返回最小值；如果 db 大于 maxDb，返回最大值
    if (db <= minDb) return minColor;
    if (db >= maxDb) return maxColor;

    // 对数映射公式：log10(dB) 映射到 [minColor, maxColor] 区间
    double logDb = log(db) / log(10); // 转换 dB 为对数值，log10(dB)
    double logMinDb = log(minDb) / log(10); // 转换 minDb 为对数值
    double logMaxDb = log(maxDb) / log(10); // 转换 maxDb 为对数值

    // 对数插值计算：通过对数比例计算 RGB 值
    double scale = (logDb - logMinDb) / (logMaxDb - logMinDb);

    // 根据 scale 返回计算出来的 RGB 值
    return ((scale * (maxColor - minColor) + minColor).toInt()).clamp(minColor, maxColor);
  }
}
